using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SmlEngine
{
    /// <summary>
    /// Currently unused.
    /// </summary>
    public static class SpriteBatchExtensions
    {
        private static Texture2D blank;
        private static bool initialized;

        private static void Initialize(this SpriteBatch spriteBatch)
        {
            if (!initialized)
            {
                blank = new Texture2D(spriteBatch.GraphicsDevice, 1, 1);
                blank.SetData(new Color[] { Color.White });
                initialized = true;
            }
        }

        #region Lines

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="start">The position to start the line at.</param>
        /// <param name="length">The length in pixels of the line.</param>
        public static void DrawLine(this SpriteBatch spriteBatch, Vector2 start, int length)
        {
            spriteBatch.DrawLine(start, length, 1, Color.Black);
        }

        //public static void DrawLine(this SpriteBatch spriteBatch, Vector2 start, int width)
        //{
        //    spriteBatch.DrawLine(start, 1, width, Color.Black);
        //}

        /// <summary>
        /// Draws a colored line.
        /// </summary>
        /// <param name="start">The position to start the line at.</param>
        /// <param name="length">The length in pixels of the line.</param>
        /// <param name="color">The color of the line.</param>
        public static void DrawLine(this SpriteBatch spriteBatch, Vector2 start, int length, Color color)
        {
            spriteBatch.DrawLine(start, length, 1, color);
        }

        //public static void DrawLine(this SpriteBatch spriteBatch, Vector2 start, int width, Color color)
        //{
        //    spriteBatch.DrawLine(start, 1, width, color);
        //}

        /// <summary>
        /// Draws a colored line with a custom width.
        /// </summary>
        /// <param name="start">The position to start the line at.</param>
        /// <param name="length">The length in pixels of the line.</param>
        /// <param name="width">The width in pixels of the line.</param>
        /// <param name="color">The color of the line.</param>
        public static void DrawLine(this SpriteBatch spriteBatch, Vector2 start, int length, int width, Color color)
        {
            Initialize(spriteBatch);
            Rectangle rect = new Rectangle((int)start.X, (int)start.Y, length, width);
            spriteBatch.Draw(blank, rect, color);
        }

        #endregion

        #region Rectangles

        /// <summary>
        /// Draws a rectangle.
        /// </summary>
        /// <param name="rectangle">The rectangle's area.</param>
        public static void DrawRectangle(this SpriteBatch spriteBatch, Rectangle rectangle)
        {
            spriteBatch.DrawRectangle(rectangle, Color.Black);
        }

        /// <summary>
        /// Draws a colored rectangle.
        /// </summary>
        /// <param name="rectangle">The rectangle's area.</param>
        /// <param name="color">The color of the rectangle.</param>
        public static void DrawRectangle(this SpriteBatch spriteBatch, Rectangle rectangle, Color color)
        {
            Initialize(spriteBatch);
            spriteBatch.Draw(blank, rectangle, color);
        }

        /// <summary>
        /// Draws a colored rectangle using vectors.
        /// </summary>
        /// <param name="start">The top-left corner of the rectangle.</param>
        /// <param name="end">The size of the rectangle.</param>
        /// <param name="color">The color of the rectangle.</param>
        public static void DrawRectangle(this SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color)
        {
            spriteBatch.DrawRectangle(new Rectangle((int)start.X, (int)start.Y, (int)(end.X - start.X), (int)(end.Y - start.Y)), color);
        }

        /// <summary>
        /// Draws a colored rectangle using integers for positioning.
        /// </summary>
        /// <param name="x">The X-coordinate of the position.</param>
        /// <param name="y">The Y-coordinate of the position.</param>
        /// <param name="width">The width of the rectangle.</param>
        /// <param name="height">The height of the rectangle.</param>
        /// <param name="color">The color of the rectangle.</param>
        public static void DrawRectangle(this SpriteBatch spriteBatch, int x, int y, int width, int height, Color color)
        {
            spriteBatch.DrawRectangle(new Rectangle(x, y, width, height), color);
        }

        #endregion

        #region Bordered Rectangles

        /// <summary>
        /// Draws a bordered rectangle.
        /// </summary>
        /// <param name="rectangle">The area of the rectangle.</param>
        /// <param name="borderWidth">The width in pixels of the border.</param>
        /// <param name="fillColor">The color to fill the rectangle.</param>
        /// <param name="borderColor">The color of the rectangle's border.</param>
        public static void DrawBorderedRectangle(this SpriteBatch spriteBatch, Rectangle rectangle, int borderWidth, Color fillColor, Color borderColor)
        {
            Initialize(spriteBatch);

            spriteBatch.DrawRectangle(rectangle, fillColor);

            if (borderWidth != 0)
            {
                spriteBatch.DrawLine(new Vector2(rectangle.Left, rectangle.Top), borderWidth, rectangle.Height, borderColor);                  // Left
                spriteBatch.DrawLine(new Vector2(rectangle.Right - borderWidth, rectangle.Top), borderWidth, rectangle.Height, borderColor);   // Right
                spriteBatch.DrawLine(new Vector2(rectangle.Left, rectangle.Top), rectangle.Width, borderWidth, borderColor);                   // Top
                spriteBatch.DrawLine(new Vector2(rectangle.Left, rectangle.Bottom - borderWidth), rectangle.Width, borderWidth, borderColor);  // Bottom
            }
        }

        #endregion

        #region Rounded Rectangles

        /// <summary>
        /// Unfinished!!! Do not use.
        /// </summary>
        public static void DrawRoundedRectangle(this SpriteBatch spriteBatch, Rectangle rectangle, short radius, Color color)
        {
            Initialize(spriteBatch);

            //Draw middle rectangle
            spriteBatch.DrawRectangle(new Rectangle(rectangle.X, rectangle.Y + radius, rectangle.Width, rectangle.Height - 2 * radius), color);

            //Draw center rectangle
            spriteBatch.DrawRectangle(new Rectangle(rectangle.X + radius, rectangle.Y, rectangle.Width - 2 * radius, rectangle.Height), color);

            //Draw corners
            for (float theta = 0; theta <= 90; theta += 0.1f) //Bottom left
            {
                float x = (float)(radius * Math.Cos(theta) + rectangle.X + radius);
                float y = (float)(radius * Math.Sin(theta) + rectangle.Bottom - radius);

                spriteBatch.Draw(blank, new Vector2(x, y), color);
            }

            for (float theta = 90; theta <= 180; theta += 0.1f) //Top left
            {
                float x = (float)(radius * Math.Cos(theta) + rectangle.X + radius);
                float y = (float)(radius * Math.Sin(theta) + rectangle.Y + radius);

                spriteBatch.Draw(blank, new Vector2(x, y), color);
            }

            for (float theta = 180; theta <= 270; theta += 0.1f) //Top right
            {
                float x = (float)(radius * Math.Cos(theta) + rectangle.Right - radius);
                float y = (float)(radius * Math.Sin(theta) + rectangle.Y + radius);

                spriteBatch.Draw(blank, new Vector2(x, y), color);
            }

            for (float theta = 270; theta <= 360; theta += 0.1f) //Bottom right
            {
                float x = (float)(radius * Math.Cos(theta) + rectangle.Right - radius);
                float y = (float)(radius * Math.Sin(theta) + rectangle.Bottom - radius);

                spriteBatch.Draw(blank, new Vector2(x, y), color);
            }
        }

        #endregion
    }
}
